//
//  Trade_VC.m
//  KaChing_App
//
//  Created by Jordan Robert Yust on 4/6/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "Trade_VC.h"
#import "Constants.h"

@implementation Trade_VC

@synthesize dataManager;
@synthesize numberFormatter;
@synthesize availableCashNumber;
@synthesize stockPrice;
@synthesize quantityNumber;
@synthesize totalPrice;

@synthesize portfolio;
@synthesize stockTicker;

@synthesize action_actionSheet;
@synthesize tradeSummary_alertView;
@synthesize successfulTrade_alertView;

@synthesize availableCashLabel_Top;
@synthesize stockPriceLabel;
@synthesize actionTypeLabel;
@synthesize tradeHeaderLabel;
@synthesize quantityTextField;
@synthesize totalPriceTextField;
@synthesize smallHeaderLabel;
@synthesize tradeButton;

/*
// Override initWithNibName:bundle: to load the view using a nib file then perform additional customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically.
- (void)loadView {
}
*/

// Implement viewDidLoad to do additional setup after loading the view.
- (void)viewDidLoad
{
	/* Set the color of the header labels to be the custom color */
	tradeHeaderLabel.backgroundColor = [UIColor customSeaFoamGreen];
	smallHeaderLabel.backgroundColor = [UIColor customSeaFoamGreen];
	
	[self createFormatters];	// Creates the formatters
	[self refreshData];	// Obtains all stock info from kaChing API
	
	[super viewDidLoad];
}

/* 
 - (void)viewWillAppear:(BOOL)animated {
 [super viewWillAppear:animated];
}
*/
/*
 - (void)viewDidAppear:(BOOL)animated {
 [super viewDidAppear:animated];
 }
 */
/*
 - (void)viewWillDisappear:(BOOL)animated {
 [super viewWillDisappear:animated];
 }
 */

/* This method is entered each time the view disappears from the screen */
 - (void)viewDidDisappear:(BOOL)animated
{
	/* Transitions back to the view displaying the stock information */
	[self.navigationController popViewControllerAnimated:TRUE];
	
	[super viewDidDisappear:animated];
 }


/*
 ------------------------------------------------------------------------
 Private Methods
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark Private Methods


- (void) createFormatters
{
	/* NUMBER FORMATTER CREATION */
	if (numberFormatter == nil)
	{
		numberFormatter = [[NSNumberFormatter alloc] init];
		[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
		[numberFormatter setPositiveFormat:@"###,##0.00"];
		[numberFormatter setNegativeFormat:@"-###,##0.00"];
		NSLocale *usLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
		[numberFormatter setLocale:usLocale];
		[usLocale release];
	}
}

- (void) updateTotalPrice
{
	/* Updates the total price text displays */
	self.totalPriceTextField.text = [NSString stringWithFormat:@"%@",[numberFormatter stringFromNumber:totalPrice]];
	
	
}

/* This method determines if the trade can be made given the specifics of the user's profile (e.g., available cash, stocks in portfolio, etc.).
 The "checking criteria" to be conducted is determined by the string parameter. "Buy" requires certain checking mechanisms, "Sell" requires other
 checking mechanisms, etc.
 This method returns a boolean value signifying whether the trade can be made. */
- (BOOL) checkTradeCriteria_ForAction:(NSString *) actionType
{
	/* If the action type is "Buy" */
	if ([actionType isEqualToString:@"Buy"])
	{
		/* If the available cash is less than the amount of cash involved in the trade */
		if ([availableCashNumber doubleValue] < [totalPrice doubleValue])
		{
			/* Displays an AlertView showing insufficient criteria */
			UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Insufficient cash" message:@"Your order cannot be processed because you do not have enough cash to make the trade."
														   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
			[alert show];
			[alert release];
			
			/* Return false (meaning trade can NOT be made) */
			return FALSE;
		}
		/* The available cash is more than the amount involved in the trade */
		else
		{
			NSLog(@"Can make trade!!!");
			
			/* Return true (meaning trade CAN be made) */
			return TRUE;
		}
		
	}
	/* If the action type is "Sell" */
	else if ([actionType isEqualToString:@"Sell"])
	{
		// Obtains the dictionary of longHoldings
		NSDictionary *longHoldingsDictionary = [portfolio objectForKey:@"longHoldings"];
		
		/* If the user doesn't have stocks for the ticker */
		if ([longHoldingsDictionary objectForKey:stockTicker] == nil)
		{
			/* Displays an AlertView showing insufficient criteria */
			UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"No %@ to sell", stockTicker] 
															message:[NSString stringWithFormat:@"Your order cannot be processed because you currently do not hold any %@ shares to sell.", stockTicker]
														   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
			[alert show];
			[alert release];
			
			/* Return false (meaning trade can NOT be made) */
			return FALSE;
		}
		/* The user does have stocks for the ticker (ticker is included in the longHoldings Dictionary) */
		else
		{
			NSLog(@"Stock IS contained in profile!!!");
			
			/* Get the number of stocks the user has for this ticker */
			NSDictionary *stockDictionary = [longHoldingsDictionary objectForKey:stockTicker];	// Get the stock dictionary
			int stockQuantity_OfUser = [[stockDictionary objectForKey:@"quantity"] intValue];	// Get the quantity of the stock

			/* If user's number of stocks is less then the number of stocks to sell */
			if (stockQuantity_OfUser < [quantityNumber floatValue])
			{
				/* Displays an AlertView showing insufficient criteria */
				UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Insufficient shares" 
																message:[NSString stringWithFormat:@"Your order cannot be processed because you can only sell %d shares of %@.", stockQuantity_OfUser, stockTicker]
															   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
				[alert show];
				[alert release];
				
				/* Return false (meaning trade can NOT be made) */
				return FALSE;
			}
			/* The user has enough stocks to sell the desired amount */
			else
			{
				NSLog(@"Does has enough stocks!!!");
				
				/* Return true (meaning trade CAN be made) */
				return TRUE;
			}
		}
	}
	/* If the action type is "Short Sell" */
	else if ([actionType isEqualToString:@"Short Sell"])
	{
		// Obtains the dictionary of longHoldings
		NSDictionary *longHoldingsDictionary = [portfolio objectForKey:@"longHoldings"];
		
		float totalMoney_Long = 0.0;	// Initialize the total money for long holdings
		
		/* Loop through all long holdings */
		for (NSString *key in [longHoldingsDictionary allKeys])
		{
			/* Gets the number of shares and the current price of each stock in the longholdings */
			float numShares = [[[longHoldingsDictionary objectForKey:key] valueForKey:@"quantity"] floatValue];
			float lastPrice = [[[longHoldingsDictionary objectForKey:key] valueForKey:@"lastPrice"] floatValue];
		
			/* Sum the total money for long holdings (num stocks * price of stock) */
			totalMoney_Long += (numShares * lastPrice);
		}
		/* NOTE: At this point, we know what the total cash is for the long holdings */
		
		/* The user's current short collateral */
		float currentShortCollateral = [[portfolio objectForKey:@"shortCollateral"] floatValue];

		/* The user's allowed collateral amount (total).  Note: This equation is based off equation in KaChing's FAQs */
		float allowedShortCollateral = 0.67 * (totalMoney_Long + [availableCashNumber floatValue] + currentShortCollateral);
		
		/* If the total price the Short Sell would be is more than the allowed amount */
		if ([totalPrice floatValue] > allowedShortCollateral)
		{
			NSLog(@"Can't short sell.  Allowed short sell is: %f", allowedShortCollateral);
			
			/* Return false (meaning trade can NOT be made) */
			return FALSE;
		}
		/* The total price is not more than the allowed amount */
		else
		{
			NSLog(@"CAN short sell!!");
			
			/* Return true (meaning trade CAN be made) */
			return TRUE;
		}
	}
	/* If the action type is "Buy to Cover" */
	else
	{
		// Obtains the dictionary of shortHoldings
		NSDictionary *shortHoldingsDictionary = [portfolio objectForKey:@"shortHoldings"];
		
		/* If the user doesn't have stocks for the ticker */
		if ([shortHoldingsDictionary objectForKey:stockTicker] == nil)
		{
			/* Displays an AlertView showing insufficient criteria */
			UIAlertView *alert = [[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"No %@ to cover", stockTicker] 
															message:[NSString stringWithFormat:@"Your order cannot be processed because you currently do not hold any %@ shares to cover.", stockTicker]
														   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
			[alert show];
			[alert release];
			
			/* Return false (meaning trade can NOT be made) */
			return FALSE;
		}
		/* The user does have short stocks for the ticker */
		else
		{
			NSLog(@"Stock IS contained in short holdings!!!");
			
			/* Get the number of stocks the user has for this ticker */
			NSDictionary *stockDictionary = [shortHoldingsDictionary objectForKey:stockTicker];	// Get the stock dictionary
			int stockQuantity_OfUser = 0 - [[stockDictionary objectForKey:@"quantity"] intValue];	// Get the quantity of the stock

			/* If user's number of stocks is less then the number of stocks to sell */
			if (stockQuantity_OfUser < [quantityNumber floatValue])
			{
				/* Displays an AlertView showing insufficient criteria */
				UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Insufficient shares" 
																message:[NSString stringWithFormat:@"Your order cannot be processed because you can cover only %d shares of %@.", stockQuantity_OfUser, stockTicker]
															   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
				[alert show];
				[alert release];
				
				/* Return false (meaning trade can NOT be made) */
				return FALSE;
			}
			/* The user has enough stocks to sell the desired amount */
			else
			{
				NSLog(@"Does have enough stocks!!!");
				
				/* Return true (meaning trade CAN be made) */
				return TRUE;
			}
		}
	}
}

/*
 ------------------------------------------------------------------------
Network Calls
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark Network Calls

/* This method performs a KaChing API call to get the user's portfolio */
-(void) getPortfolioInfo
{
	/* KaChing API calls */
	[self setPortfolio:[dataManager getPortfolio]];		// Get user's portfolio
	
	/* Sets the available cash number */
	[self setAvailableCashNumber:[NSNumber numberWithFloat:[[portfolio objectForKey:@"availableCash"] floatValue]]];
	
	/* Updates the available cash label */
	NSString *availableCash_String =[NSString stringWithFormat:@"$%@", [numberFormatter stringFromNumber:availableCashNumber]];
	availableCashLabel_Top.text = availableCash_String;
}

/* This method performs a KaChing API call to get the stock ticker's info (price, etc.) */
-(void) getTickerInfo
{
	// Get the stock with the given ticker
	NSDictionary *tickerDictionary = (NSDictionary *)[self.dataManager getSecurity:stockTicker];

	/* Updates the price of the stock */
	for (NSString *key in [tickerDictionary allKeys])
	{
		/* Updates the actual price (an NSNumber) */
		NSDictionary *stockDictionary = (NSDictionary *) [tickerDictionary objectForKey:key];	// Get's the stock's dictionary
		[self setStockPrice:[NSNumber numberWithFloat:[[stockDictionary valueForKey:@"lastRealTimePrice"] floatValue]]];
		
		/* Updates the label corresponding to the price */
		stockPriceLabel.text = [NSString stringWithFormat:@"$%@", [numberFormatter stringFromNumber:stockPrice]];
	}
}

/*
 ------------------------------------------------------------------------
 IBAction Methods
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark IBAction Methods

/* This method makes several KaChing API calls and updates the apropriate data */
- (IBAction) refreshData
{
	[self getPortfolioInfo];	// Gets the user's porfolio from KaChing	
	[self getTickerInfo];		// Gets stock ticker info from KaChing
}

/* This method is called when the button is pushed to update either the quantity or total price textfields */
- (IBAction) updateTradeCalculations
{
	/* If the quantity was being edited instead of total price */
	if ([self.quantityTextField isEditing])
	{
		/* Hides the keyboard */
		[quantityTextField resignFirstResponder];
		
		/* Updates the quantity NSNumber with the number in the textfield */
		[self setQuantityNumber:[NSNumber numberWithInt:[quantityTextField.text intValue]]];
		
		/* Calculates the total price (price of stock * quantity) */
		[self setTotalPrice:[NSNumber numberWithDouble:(double)[stockPrice floatValue] * [quantityNumber intValue]]];

		/* Updates the appropriate information */
		[self updateTotalPrice];
		
	}
	/* If the total price was being edited instead of quantity */
	else if ([self.totalPriceTextField isEditing])
	{
		/* Hides the keyboard */
		[totalPriceTextField resignFirstResponder];
		
		/* Calculates the quantity by doing this: total price (currently entered) / price of each stock */
		[self setQuantityNumber:[NSNumber numberWithInt:([totalPriceTextField.text floatValue] / [stockPrice floatValue])]];
		quantityTextField.text =  [quantityNumber stringValue];
		
		/* Caclulates the total price (price of stock * quantity) */
		[self setTotalPrice:[NSNumber numberWithDouble:(double)[stockPrice floatValue] * [quantityNumber intValue]]];

		/* Updates the appropriate information */
		[self updateTotalPrice];
	}
}

/* This method is used to specify which action type the trade will be (buy, sell, short sell, buy to cover) */
- (IBAction) changeActionType
{
	NSLog(@"ChangeActionType entered!!");
	
	/* Create an actionSheet with the appropriate options for managing the profile */
	UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"Which action do you want to take?"
													delegate:self cancelButtonTitle:@"Cancel" destructiveButtonTitle:nil
													otherButtonTitles:@"Buy", @"Sell", @"Short Sell", @"Buy to Cover", nil];
	actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
	[actionSheet showInView:self.view]; // show from our table view (pops up in the middle of the table)
	
	[self setAction_actionSheet:actionSheet];
	[actionSheet release];
	
	NSLog(@"ChangeActionType exited!!");
}

/* This method performs a trade based on the information currently in each of the fields in the view (quantity, total, and action type) */
- (IBAction) performTrade
{	
	/* If no quantity is specified */
	if ([quantityNumber intValue] == 0)
	{
		/* Displays an AlertView showing insufficient criteria */
		UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No Quantity" message:@"Please specify the quantity."
													   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
		[alert show];
		[alert release];
	}
	/* There is a quantity specified */
	else
	{
		/* Get the most recent stock information before making trade */
		[self refreshData];
	
		/* Calculates the total price (price of stock * quantity) */
		[self setTotalPrice:[NSNumber numberWithDouble:(double)[stockPrice floatValue] * [quantityNumber intValue]]];
	
		/* Updates the appropriate information for the total price */
		[self updateTotalPrice];

		/* Determine if the trade is allowed or not */
		BOOL canTradeStock = [self checkTradeCriteria_ForAction:actionTypeLabel.text];
	
		/* The trade can be made... */
		if (canTradeStock)
		{
			/* Displays an AlertView showing trade sumary (in order for User to confirm its correct) */
			NSString *tradeSummaryString = [NSString stringWithFormat:@"Order: Market\nAction: %@\nQuantity: %d\nTotal: $%@", actionTypeLabel.text, [quantityNumber intValue], totalPriceTextField.text];
						
			UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Trade Summary" message:tradeSummaryString
														   delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"OK", nil];
			[alert show];
			[self setTradeSummary_alertView:alert];
			[alert release];
		}
	}
	
	NSLog(@"Perform Trade method exited!!");
}

/*
 ------------------------------------------------------------------------
 UITextFieldDelegate protocol methods
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark UITextFieldDelegate protocol methods

/* This method is called whenever the user taps the return method.
 NOTE: This method is part of the UITextFieldDelegate Protocol.
 */
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
	/* Resign First Responder (hide the keyboard) */
	if (textField == self.quantityTextField || textField == self.totalPriceTextField)
	{
		[textField resignFirstResponder];
	}
	
	return YES;
}

/* This method is called whenever a textField is entered into (i.e., begin entering text into it) */
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
	if (textField == self.quantityTextField || textField == self.totalPriceTextField)
	{
		/* Since a value is being entered into the text field, hid the trade button again */
		tradeButton.hidden = TRUE;
		
		/* Set the animations and specify the amount of time frame will animate */
		[UIView beginAnimations:nil context:NULL];
		[UIView setAnimationDuration:0.3];
		
		// Make changes to the view's frame inside the animation block. They will be animated instead
		// of taking place immediately.
		CGRect rect = self.view.frame;
		
		// Since moving the view up, not only decrease the origin but increase the height so the view 
		// covers the entire screen behind the keyboard.
		rect.origin.y -= keypad_offset_forTrade;
		rect.size.height += keypad_offset_forTrade;

		self.view.frame = rect;
		
		[UIView commitAnimations];
		
		/* Disable the other textField that is currently not being edited */
		if (textField == self.quantityTextField)
			self.totalPriceTextField.enabled = FALSE;
		else
			self.quantityTextField.enabled = FALSE;
	}
}

/* This method is called whenever a textField is exited (i.e., finished entering text into it) */
- (void)textFieldDidEndEditing:(UITextField *)textField
{
	if (textField == self.quantityTextField || textField == self.totalPriceTextField)
	{
		/* Since a value has been entered into the text field, display the trade button again */
		tradeButton.hidden = FALSE;
		
		/* Set the animations and specify the amount of time frame will animate */
		[UIView beginAnimations:nil context:NULL];
		[UIView setAnimationDuration:0.3];
		
		// Make changes to the view's frame inside the animation block. They will be animated instead
		// of taking place immediately.
		CGRect rect = self.view.frame;

		// Since moving down, not only increase the origin but decrease the height.
		rect.origin.y += keypad_offset_forTrade;
		rect.size.height -= keypad_offset_forTrade;

		self.view.frame = rect;
		
		[UIView commitAnimations];
		
		/* Re-enable the other textfield */
		if (textField == self.quantityTextField)
			self.totalPriceTextField.enabled = TRUE;
		else
			self.quantityTextField.enabled = TRUE;
	}
}

/*
 ------------------------------------------------------------------------
 UIAlertView Delegate methods
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark UIAlertView Delegate methods

/*
 This method is called whenever a button in an AlertView is clicked in the current view. 
 NOTE: This method is part  of the UIAlertViewDelegate protocol.
 The 'alertView' parameter is the actual AlertView object.
 The 'buttonIndex' parameter is the index number of the button that was pressed in the AlertView.
 */
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
	/* If the alertView parameter is the tradeSummary alertView */
	if (alertView == tradeSummary_alertView)
	{
		/* If the button confirming the trade should take place was pressed.. */
		if (buttonIndex == performTrade_AlertViewIndex)
		{
			NSString *actionType;
			
			if (actionTypeLabel.text == @"Short Sell")
				actionType = @"short";
			else if (actionTypeLabel.text == @"Buy to Cover")
				actionType = @"cover";
			else
				actionType = actionTypeLabel.text;
			
			NSString *orderType = @"market-order";
			NSString *limitPrice = @"";
			NSString *endOfDay = @"";
			 
			// KaChing API call - make the trade
			[dataManager trade:stockTicker By:actionType And:orderType For:quantityTextField.text If:limitPrice By:endOfDay];
			
			NSLog(@"*************");
			NSLog(@"Symbol: %@", stockTicker);
			NSLog(@"Action: %@", actionType);
			NSLog(@"Type: %@", orderType);
			NSLog(@"Quantity: %@", quantityTextField.text);
			NSLog(@"Limit: %@", limitPrice);
			NSLog(@"EndOfDay: %@", endOfDay);
			
			/* Displays an AlertView showing successful trade */
			UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Trade Successful!" message:@"Your order was processed successfully."
														   delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
			[alert show];
			[self setSuccessfulTrade_alertView:alert];
			[alert release];
			

		}		
	}
	/* If the alertView parameter is the successfulTrade alertView */
	else if (alertView == successfulTrade_alertView)
	{
		/* Transitions back to the view displaying the stock information */
		[self.navigationController popViewControllerAnimated:TRUE];
	}
}

/*
 ------------------------------------------------------------------------
 UIActionSheetDelegate methods
 ------------------------------------------------------------------------
 */

#pragma mark -
#pragma mark UIActionSheetDelegate methods

/*
 This method is called whenever a button in an ActionSheet is clicked in the current view. 
 NOTE: This method is part  of the UIActionSheetDelegate protocol.
 The 'actionSheet' parameter is the actual ActionSheet object.
 The 'buttonIndex' parameter is the index number of the button that was pressed in the ActionSheet.
 */
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
	/* If the parameter is the actionsheet instance (should always be the case) */
	if (actionSheet == action_actionSheet)
	{
		/* Updates the label's text with the appropriate string */
		if (buttonIndex == buy_ActionSheetIndex)
		{
			actionTypeLabel.text = @"Buy";
		}
		else if (buttonIndex == sell_ActionSheetIndex)
		{
			actionTypeLabel.text = @"Sell";
		}
		else if (buttonIndex == shortSell_ActionSheetIndex)
		{
			actionTypeLabel.text = @"Short Sell";
		}
		else if (buttonIndex == buy2Cover_ActionSheetIndex)
		{
			actionTypeLabel.text = @"Buy to Cover";
		}
	}
}


#pragma mark -

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
    // Release anything that's not essential, such as cached data
}


- (void)dealloc
{
	[dataManager release];
	[numberFormatter release];
	[availableCashNumber release];
	[stockPrice release];
	[quantityNumber release];
	[totalPrice release];
	[portfolio release];
	[stockTicker release];
	[action_actionSheet release];
	[tradeSummary_alertView release];
	[successfulTrade_alertView release];
	[availableCashLabel_Top release];
	[stockPriceLabel release];
	[actionTypeLabel release];
	[tradeHeaderLabel release];
	[quantityTextField release];
	[totalPriceTextField release];
	[smallHeaderLabel release];
	[tradeButton release];
    [super dealloc];
}


@end
